#ifdef _WIN32
#include <io.h>
#endif
#include <lvos.h>
#include <log.h>
#include <framework.h>
#include <SessionManager.h>

STATUS LVOS_Write(const TextTable &t, int fd)
{
    COND_CHECK_RET_ERROR((fd < 0));

    COND_CHECK_RET_ERROR(!t.has_columns());

    std::ostringstream oss;
    oss << t << "Tatol: " << (t.rows().size() - 1) << " record" << std::endl;
    return LVOS_Write(oss, fd);
}
STATUS LVOS_Write(const std::ostringstream &oss, int fd)
{
    COND_CHECK_RET_ERROR((fd < 0));

    const std::string& outString = oss.str();
    return LVOS_Write(outString, fd);
}

STATUS LVOS_Write(const std::string &str, int fd)
{
    COND_CHECK_RET_ERROR((fd < 0));
    return LVOS_Write(str.c_str(), static_cast<int>(str.length()), fd);
}

STATUS LVOS_Write(const void* _Buf, unsigned int _MaxCharCount, int fd)
{
    unsigned int total = 0;
    int bytes_written;

    COND_CHECK_RET_ERROR((fd < 0));

    do
    {
        bytes_written = (int)FMT_POSIX_CALL(write)(fd, ((char*)_Buf + total), _MaxCharCount - total);

        if (bytes_written < 0)
        {
            if (errno == EINTR)
            {
                continue;
            }
            return RET_ERROR;
        }
        else if (bytes_written == 0)
        {
            return RET_ERROR;
        }
        else
        {
            total += (unsigned int)bytes_written;
        }

    } while (total != _MaxCharCount);

    return OK;
}

STATUS LVOS_Write(const TextTable& t, SessionPtr session)
{
    COND_CHECK_RET_ERROR(!t.has_columns());

    std::ostringstream oss;
    oss << t << "Tatol: " << (t.rows().size() - 1) << " record" << std::endl;
    return LVOS_Write(oss, session);
}

STATUS LVOS_Write(const std::ostringstream& oss, SessionPtr session)
{
    const std::string& outString = oss.str();
    return LVOS_Write(outString, session);
}

STATUS LVOS_Write(const std::string& str, SessionPtr session)
{
    session->appendWriteData(str);
    return OK;
}

STATUS LVOS_Report(const TextTable& t)
{
    COND_CHECK_RET_ERROR(!t.has_columns());

    std::ostringstream oss;
    oss << std::endl << t << std::endl;
    return LVOS_Report(oss);
}

STATUS LVOS_Report(const std::ostringstream& oss)
{
    const std::string& outString = oss.str();
    return LVOS_Report(outString);
}


STATUS LVOS_Report(const std::string& str)
{
    return GET_FRAMEWORK_MGR->callObjectMethod<SessionManager, STATUS>
        (MODULE_TELNET_MGR, &SessionManager::reportEvent, str);
}